package com.puntodonna.fogliocassa.server.action;

import java.util.ArrayList;
import java.util.Iterator;

import com.google.inject.Inject;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.ObjectifyService;
import com.gwtplatform.dispatch.server.ExecutionContext;
import com.gwtplatform.dispatch.server.actionhandler.ActionHandler;
import com.gwtplatform.dispatch.shared.ActionException;
import com.puntodonna.fogliocassa.client.action.PersistanceAction;
import com.puntodonna.fogliocassa.client.action.PersistanceActionResult;
import com.puntodonna.fogliocassa.shared.FoglioCassaObj;
import com.puntodonna.fogliocassa.shared.MovimentoObj;
import com.puntodonna.fogliocassa.shared.UserObj;

public class PersistanceActionActionHandler implements ActionHandler<PersistanceAction, PersistanceActionResult> {

	protected boolean init = false;

	@Inject
	public PersistanceActionActionHandler() {

	}

	@Override
	public PersistanceActionResult execute(PersistanceAction action, ExecutionContext context) throws ActionException {
		
		if (!isInit()) {
			ObjectifyService.register(FoglioCassaObj.class);
			ObjectifyService.register(MovimentoObj.class);
			ObjectifyService.register(UserObj.class);
			this.init = true;
		}

		String actionStr = action.getAction();
		PersistanceActionResult persistanceActionResult = null;
		if (actionStr.equals(PersistanceAction.ACTION_FC_GETALL)) {
			UserObj userObj = action.getUserObj();
			ArrayList<FoglioCassaObj> fogliCassaCollection = new ArrayList<FoglioCassaObj>(ObjectifyService.factory().begin().load().type(FoglioCassaObj.class).filter("userObjKey", userObj).list());
			for (Iterator<FoglioCassaObj> iterator = fogliCassaCollection.iterator(); iterator.hasNext();) {
				FoglioCassaObj foglioCassaObj = (FoglioCassaObj) iterator.next();
				Iterator<MovimentoObj> movimenti = ObjectifyService.factory().begin().load().type(MovimentoObj.class).filter("foglioCassaKey", foglioCassaObj).list().iterator();
				while (movimenti.hasNext()) {
					MovimentoObj movimentoObj = movimenti.next();
					foglioCassaObj.add(movimentoObj);
				}
			}
			persistanceActionResult = new PersistanceActionResult(actionStr, fogliCassaCollection);
		} else if (actionStr.equals(PersistanceAction.ACTION_FC_SAVE) || (actionStr.equals(PersistanceAction.ACTION_FC_UPDATE))) {
			FoglioCassaObj foglioCassaObj = action.getFoglioCassaObj();
			UserObj userObj = action.getUserObj();
			foglioCassaObj.setUserObjKey(Key.create(UserObj.class, userObj.getId()));
			ObjectifyService.factory().begin().save().entities(foglioCassaObj).now();
			Iterator<MovimentoObj> movimenti = foglioCassaObj.getMovimenti().values().iterator();
			while (movimenti.hasNext()) {
				MovimentoObj movimentoObj = movimenti.next();
				movimentoObj.setFoglioCassaKey(Key.create(FoglioCassaObj.class, foglioCassaObj.getId()));
				ObjectifyService.factory().begin().save().entities(movimentoObj).now();
			}
			persistanceActionResult = new PersistanceActionResult(actionStr, foglioCassaObj);
		} else if (actionStr.equals(PersistanceAction.ACTION_FC_DELETE)) {
			FoglioCassaObj foglioCassaObj = action.getFoglioCassaObj();
			ObjectifyService.factory().begin().delete().entities(foglioCassaObj).now();
			for (Iterator<MovimentoObj> iterator = foglioCassaObj.getMovimenti().values().iterator(); iterator.hasNext();) {
				MovimentoObj movimentoObj = (MovimentoObj) iterator.next();
				ObjectifyService.factory().begin().delete().entities(movimentoObj).now();
			}
			persistanceActionResult = new PersistanceActionResult(actionStr, foglioCassaObj);
		} else if (actionStr.equals(PersistanceAction.ACTION_MV_SAVE) || actionStr.equals(PersistanceAction.ACTION_MV_UPDATE)) {
			FoglioCassaObj foglioCassaObj = action.getFoglioCassaObj();
			MovimentoObj movimentoObj = action.getMovimentoObj();
			movimentoObj.setFoglioCassaKey(Key.create(FoglioCassaObj.class, foglioCassaObj.getId()));
			ObjectifyService.factory().begin().save().entities(movimentoObj).now();
			persistanceActionResult = new PersistanceActionResult(actionStr, movimentoObj);
		} else if (actionStr.equals(PersistanceAction.ACTION_MV_DELETE)) {
			MovimentoObj movimentoObj = action.getMovimentoObj();
			ObjectifyService.factory().begin().delete().entities(movimentoObj).now();
			persistanceActionResult = new PersistanceActionResult(actionStr, movimentoObj);
		} else {
			throw new ActionException("Unknown action: " + actionStr);
		}
		return persistanceActionResult;
	}

	public boolean isInit() {
		return init;
	}

	@Override
	public void undo(PersistanceAction action, PersistanceActionResult result, ExecutionContext context) throws ActionException {
	}

	@Override
	public Class<PersistanceAction> getActionType() {
		return PersistanceAction.class;
	}
}
